#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h> 
#include "my_malloc.h"
#include "mutex.h"

/*the building-block of our stack/dequeue
 */
typedef struct mylink {
	struct mylink * up;
	char * value;
	struct mylink * down;
}mylink;

typedef struct dequeuetype {
	mylink * top;
	mylink * bottom;
	Mutex DEQlockDead;
	Mutex DEQlockUp;
	Mutex DEQlockDown;
	int counter;
}dequeue;





/*this function allocates the needed mem. - don't forget to error-check allocations
 * input: nothing
 * output: null if something went wrong or a pointer to the allocated AND INITIALIZED struct
 */
dequeue * createDequeue();

/*this function frees all the mem. allocated - you should check that everything inside the struct
 * you allocated is freed to (recursive free - yes i used the word recursive)
 *
 * input: pointer to a dequeue struct
 * output: nothing
 */
void freeDequeue(dequeue * dq);

/*a function to add a new string to the top of the dequeue
 * input: a pointer to  dequeue, a pointer to the string to add
 * output: on any mem. allocation failure return -1
 * 		   on any generic failure return 0 (if this case even exists)
 * 			on success return 1
 */
int push(dequeue *dq, char *str);

/*this function removes the top member of the dequeue from the struc
 * input: a pointer to dequeue
 * output: return 1 on success, 0 on failue
 */
int pop(dequeue *dq);

/*this function returns the string we hold at the top of the dequeue to the buffer given
 * the bufferSize is used to see if the buffer can hold the string at the top
 * and to see we don't get any seg-faults!
 * input: a pointer to a dequeue, a string buffer and the buffer's size
 * output: return 1 on success, 0 on failure
 */
int top(dequeue *dq, char *buffer, int bufferSize);


/*add here the rest of the interface for the rest of the functions we agreed on
 * and send it back to me - i'll keep working on the program usin only stack command
 * and the struct from this interface so we can work  - we don't realy have the time!
 */


/*
check if a DEQ is empty. 1=empty , 0=not.
 */
int empty(dequeue *dq);

/*
same as push - for bottom side
 */
int pushBottom(dequeue *dq, char *str);

/*
same as pop - for bottom side
 */
int popBottom(dequeue *dq);
/*
same as top - for bottom side
 */
int bottom(dequeue *dq, char *buffer, int bufferSize);
